package top.yudoge.dogeeditor.llm.rewrite

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import top.yudoge.dogeeditor.db.api.DataSourceMetaDataApi

@Component
@Deprecated(message = "This class is deprecated.")
class SQLSelfCheckingChainNode : TaskChainNode {

    @Autowired
    private lateinit var sqlGenerateChainNode: SQLGenerateChainNode

    @Autowired
    private lateinit var dataSourceMetaDataApi: DataSourceMetaDataApi

    private val MAX_RETRY_COUNT = 3

    override fun process(ctx: ChainContext) {

        sendReasoningCallback(ctx, "Self-Checking SQL...")

        val retryCount = getChainStore(ctx, RETRY_COUNT) as? Int ?: 0

        if (retryCount >= MAX_RETRY_COUNT) {
            ctx.callback.onEvent(
                RewriteEvent(
                    RewriteEventType.Error,
                    "Self-Checking SQL failed. (retry count exceeded)"
                )
            )
            return
        }

        putChainStore(ctx, RETRY_COUNT, retryCount+1)

        var generatedSQL = getChainStore(ctx, SQLGenerateChainNode.GENERATED_SQL) as? String
        if (generatedSQL.isNullOrBlank()) {
            // 没有SQL
            ctx.callback.onEvent(RewriteEvent(RewriteEventType.Complete, ""))
            return
        }
        if (!isSelectSQL(generatedSQL)) {
            ctx.callback.onEvent(RewriteEvent(RewriteEventType.Complete, ""))
        }

        var result = dataSourceMetaDataApi.executeSql(
            ctx.query.dataSourceIdentifier,
            ctx.query.databaseName,
            ctx.query.schemaName,
            generatedSQL
        )

        if (result.success) {
            println("Self-Checking pass!")
            ctx.callback.onEvent(RewriteEvent(RewriteEventType.Complete, ""))
            return
        }
        println("Self-Checking failed! ${result.errorMessage ?: "Unknown error"}")
        if (result.errorMessage.isNullOrBlank()) {
            RewriteEvent(
                RewriteEventType.Error,
                "Self-Checking SQL failed. (Unknown Error)"
            )
            return
        }
        moveBack(ctx)
        sqlGenerateChainNode.doProcess(ctx, result.errorMessage!!)
    }

    // only permit SELECT SQL(for the commercial use, you must make sure that only SELECT SQL can be executed)
    private fun isSelectSQL(generatedSQL: String): Boolean {
        if (generatedSQL.uppercase().startsWith("SELECT")) {
            return true
        }
        return false
    }


    companion object {
        private const val RETRY_COUNT = "retry_count"
    }
}